import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.neighbors import KNeighborsRegressor

# 读取数据
data = pd.read_csv('VitalDB.csv')
labels = list(data.columns.values)
print(labels)

# 标称型特征
nominal_array = list(data.select_dtypes(include=['object']))
# 数值型特征
numerical_array = list(data.select_dtypes(include = ['int','float']))

print(nominal_array)
print(numerical_array)

for column_name in nominal_array:
# 数据摘要
# 标称属性，给出每个可能取值的频数
    print(data[f'{column_name}'].value_counts())
# 数值属性，给出5数概括及缺失值的个数
    print(data[f'{column_name}'].describe())
    print('Number of missing values:', data[f'{column_name}'].isnull().sum())

for column_name in numerical_array:
# 数据摘要
# 标称属性，给出每个可能取值的频数
    print(data[f'{column_name}'].value_counts())
# 数值属性，给出5数概括及缺失值的个数
    print(data[f'{column_name}'].describe())
    print('Number of missing values:', data[f'{column_name}'].isnull().sum())

# 数据可视化
# 使用直方图检查数据分布及离群点
    data[f'{column_name}'].hist(bins=50)
    plt.show()

# 使用盒图检查数据分布及离群点
    sns.boxplot(x=data[f'{column_name}'])
    plt.show()

#将缺失部分剔除
missing_rows = data[data.isnull().any(axis=1)]
data = data.dropna(inplace=True)
pd.set_option('display.width',None)
print(missing_rows)

#用最高频率值来填补缺失值: 使用聚合值，例如平均值、中位数或众数。
mode_values = data.mode().iloc[0]
data = data.fillna(mode_values)
pd.set_option('display.width',None)
print(data)

#通过属性的相关关系来填补缺失值:
corr_values = data.corr().iloc[-1].dropna()
related_column = corr_values.abs().sort_values(ascending=False).index[1]
mean_value = data[related_column].mean()
data = data.fillna({related_column: mean_value})
pd.set_option('display.width',None)
print(data)

#通过数据对象之间的相似性来填补缺失值: 可以使用KNN算法等模型对于缺失值进行处理。
# 划分已知数据和待填充数据
known_data = data[data['intraop_ebl'].notnull()]
unknown_data = data[data['intraop_ebl'].isnull()]

knn = KNeighborsRegressor()
knn.fit(known_data[['height']], known_data['intraop_ebl'])
predicted_values = knn.predict(unknown_data[['height']])

data.loc[data['intraop_ebl'].isnull(), 'intraop_ebl'] = predicted_values
pd.set_option('display.width',None)
print(data)